#include "Input.h"

Input::Input()
{
	// setup input
	mMouse = std::make_unique<Mouse>();
	mKeyboard = std::make_unique<Keyboard>();

	mMouseWheel = 0.f;
	mMouseWheelH = 0.f;
	mInputChar = 0x10000;
}

Input& Input::Get()
{
	static Input inputInst;
	return inputInst;
}

void Input::SetWindow(HWND hwnd)
{
	mMouse->SetWindow(hwnd);
	mMouse->SetMode(Mouse::MODE_ABSOLUTE);
}

void Input::ProcessMouse(UINT message, WPARAM wParam, LPARAM lParam)
{
	mMouse->ProcessMessage(message, wParam, lParam);
}

void Input::ProcessKeyboard(UINT message, WPARAM wParam, LPARAM lParam)
{
	mKeyboard->ProcessMessage(message, wParam, lParam);
}

void Input::ProcessMouseWhell(UINT message, WPARAM wParam, LPARAM lParam)
{
	mMouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
}

void Input::ProcessMouseHWhell(UINT message, WPARAM wParam, LPARAM lParam)
{
	mMouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
}

void Input::ProcessInputChar(uint16 inputChar)
{
	mInputChar = inputChar;
}

void Input::Update()
{
	mMouseState = mMouse->GetState();
	mLastMouseState = mMouseTracker.GetLastState();
	mKeyState = mKeyboard->GetState();
	mLastKeyState = mKeyboardTracker.GetLastState();
	mMouseTracker.Update(mMouseState);
	mKeyboardTracker.Update(mKeyState);
}

bool Input::IsKeyDown(Keyboard::Keys key) const
{
	return mKeyState.IsKeyDown(key);
}

bool Input::IsKeyUp(Keyboard::Keys key) const
{
	return mKeyState.IsKeyUp(key);
}

bool Input::IsLastKeyDown(Keyboard::Keys key) const
{
	return mLastKeyState.IsKeyDown(key);
}

bool Input::IsLastKeyUp(Keyboard::Keys key) const
{
	return mLastKeyState.IsKeyUp(key);
}

bool Input::LeftButton() const
{
	return mMouseState.leftButton && mMouseTracker.leftButton == mMouseTracker.HELD;
}

bool Input::MiddleButton() const
{
	return mMouseState.middleButton;
}

bool Input::RightButton() const
{
	return mMouseState.rightButton && mMouseTracker.rightButton == mMouseTracker.HELD;
}

bool Input::XButton1() const
{
	return mMouseState.xButton1;
}

bool Input::XButton2() const
{
	return mMouseState.xButton2;
}

int32 Input::MouseX() const
{
	return mMouseState.x;
}

int32 Input::MouseY() const
{
	return mMouseState.y;
}

int32 Input::ScrollWheelValue() const
{
	return mMouseState.scrollWheelValue;
}

bool Input::LastLeftButton() const
{
	return mLastMouseState.leftButton;
}

bool Input::LastMiddleButton() const
{
	return mLastMouseState.middleButton;
}

bool Input::LastRightButton() const
{
	return mLastMouseState.rightButton;
}

bool Input::LastXButton1() const
{
	return mLastMouseState.xButton1;
}

bool Input::LastXButton2() const
{
	return mLastMouseState.xButton2;
}

int32 Input::LastMouseX() const
{
	return mLastMouseState.x;
}

int32 Input::LastMouseY() const
{
	return mLastMouseState.y;
}

int32 Input::LastScrollWheelValue() const
{
	return mLastMouseState.scrollWheelValue;
}

float Input::MouseWheel()
{
	const float result = mMouseWheel;
	mMouseWheel = 0.f;
	return result;
}

float Input::MouseWheelH()
{
	const float result = mMouseWheelH;
	mMouseWheelH = 0.f;
	return mMouseWheelH;
}

uint16 Input::InputChar()
{
	const uint16 result = mInputChar;
	mInputChar = 0x10000;
	return result;
}
